<?php

class Manager {

	const KEY_BOOTSTRAP = 'bootstrap';
	const KEY_PATH_ROOT = 'PathRoot';
	const KEY_DB_GITE_NOUETTE = 'DbGiteNouette';
	const KEY_MAPPER = 'Mapper';
	const KEY_LOCALE = 'Zend_Locale';
	const KEY_TRANSLATE = 'Zend_Translate';
	const KEY_PLUGIN_LOADER = 'Zend_PluginLoader';
	const KEY_NAVIGATION = 'Zend_Navigation';
	const KEY_FACTORY_MODEL = 'FactoryModel';
	const KEY_FACTORY_FORM = 'FactoryForm';
	const KEY_LOGGER = 'Zend_Logger';
	const KEY_ACL = 'Zend_Acl';
	const KEY_CACHE = 'Zend_Cache';
	const KEY_PAGE_CACHE = 'Zend_Page_Cache';
	const KEY_CONTROLLERS_UTILS = 'Controllers_Utils';
    const KEY_IMAGE_UTILS = 'Image_Utils';


	private static function get($key) {
		if (Zend_Registry::isRegistered($key)) {
			return Zend_Registry::get($key);
		}
		else {
			return null;
		}
	}

	private static function set($key, $entity) {
		if (!is_null($entity)) {
			Zend_Registry::set($key, $entity);
		}
	}


	public static function setBootstrap(Zend_Application_Bootstrap_Bootstrapper $bootstrap) {
		self::set(self::KEY_BOOTSTRAP, $bootstrap);
	}

	public static function getBootstrap() {
		return self::get(self::KEY_BOOTSTRAP);
	}

	public static function getPathRoot() {
		return self::get(self::KEY_PATH_ROOT);
	}

	public static function getPathApplication() {
		return self::getPathRoot().'/application';
	}

	public static function getPathResources() {
		return self::getPathApplication().'/resources';
	}

	public static function getPathFonts() {
		return self::getPathResources().'/fonts';
	}

	public static function getPathDefaultCaptchaFont() {
		return self::getPathFonts().'/Tuffy.ttf';
	}

	public static function getPathPublic() {
		return self::getPathRoot().'/public';
	}

	public static function getPathMiniatures() {
		return self::getPathPublic().'/miniatures';
	}

	public static function getPathPhotos() {
		return self::getPathPublic().'/photos';
	}

	public static function getPathCache() {
		return Manager::getPathRoot().'/cache';
	}

    public static function getPathPix() {
        return self::getPathPublic().'/pix';
    }

	public static function setPathRoot($pathRoot) {
		if (is_string($pathRoot)) {
			self::set(self::KEY_PATH_ROOT, $pathRoot);
		}
	}

	public static function getDbGiteNouette() {
		if (is_null(self::get(self::KEY_DB_GITE_NOUETTE))) {
			self::initDb();
			self::getLogger()->log(self::getCurrentStackTrace("New database connection"), Zend_Log::INFO);
		}

		if (is_null(self::get(self::KEY_DB_GITE_NOUETTE))) {
			self::getLogger(false)->log("Unable to get a database connection", Zend_Log::EMERG);
		}

		return self::get(self::KEY_DB_GITE_NOUETTE);
	}

	public static function setDbGiteNouette(Zend_Db_Adapter_Abstract $db) {
		self::set(self::KEY_DB_GITE_NOUETTE, $db);
	}

	public static function getMapper() {
		return self::get(self::KEY_MAPPER);
	}

	public static function setMapper(Utils_Mapper $mapper) {
		self::set(self::KEY_MAPPER, $mapper);
	}

	public static function getLocale() {
		return self::get(self::KEY_LOCALE);
	}

	public static function setLocale(Zend_Locale $locale) {
		self::set(self::KEY_LOCALE, $locale);
	}

	public static function getTranslate() {
		return self::get(self::KEY_TRANSLATE);
	}

	public static function setTranslate(Zend_Translate $translate) {
		self::set(self::KEY_TRANSLATE, $translate);
	}

	public static function getPluginLoader() {
		return self::get(self::KEY_PLUGIN_LOADER);
	}

	public static function setPluginLoader(Zend_Loader_PluginLoader_Interface $pluginLoader) {
		self::set(self::KEY_PLUGIN_LOADER, $pluginLoader);
	}

	public static function getNavigation() {
		return self::get(self::KEY_NAVIGATION);
	}

	public static function setNavigation(Zend_Navigation $navigation) {
		self::set(self::KEY_NAVIGATION, $navigation);
	}

	public static function getFactoryModel() {
		return self::get(self::KEY_FACTORY_MODEL);
	}

	public static function setFactoryModel(Factory_FactoryModel $factoryModel) {
		self::set(self::KEY_FACTORY_MODEL, $factoryModel);
	}

	public static function getFactoryForm() {
		return self::get(self::KEY_FACTORY_FORM);
	}

	public static function setFactoryForm(Factory_FactoryForm $factoryForm) {
		self::set(self::KEY_FACTORY_FORM, $factoryForm);
	}

	public static function getLogger($availableDb = true) {
		if (is_null(self::get(self::KEY_LOGGER))) {
			self::initLog($availableDb);
		}

		return self::get(self::KEY_LOGGER);
	}

	public static function setLogger(Zend_Log $logger) {
		self::set(self::KEY_LOGGER, $logger);
	}

	public static function getAcl() {
		return self::get(self::KEY_ACL);
	}

	public static function setAcl(Zend_Acl $acl) {
		self::set(self::KEY_ACL, $acl);
	}

	public static function getCache() {
		return self::get(self::KEY_CACHE);
	}

	public static function setCache($cache) {
		self::set(self::KEY_CACHE, $cache);
	}

	public static function getPageCache() {
		return self::get(self::KEY_PAGE_CACHE);
	}

	public static function setPageCache($pageCache) {
		self::set(self::KEY_PAGE_CACHE, $pageCache);
	}

	public static function getControllersUtils() {
		if (is_null(self::get(self::KEY_CONTROLLERS_UTILS))) {
			self::setControllersUtils(new Controllers_Utils());
		}

		return self::get(self::KEY_CONTROLLERS_UTILS);
	}

	private static function setControllersUtils($controllersUtils) {
		self::set(self::KEY_CONTROLLERS_UTILS, $controllersUtils);
	}

    /**
     * @return Utils_Image
     */
    public static function getImageUtils() {
        if (is_null(self::get(self::KEY_IMAGE_UTILS))) {
            self::setImageUtils(new Utils_Image('/', Manager::getPathPix()));
        }

        return self::get(self::KEY_IMAGE_UTILS);
    }

    private static function setImageUtils($imageUtils) {
        self::set(self::KEY_IMAGE_UTILS, $imageUtils);
    }

	public static function saveException(Exception $exception) {
		$front = Zend_Controller_Front::getInstance();
		$errorPlugin = $front->getPlugin('Plugins_ErrorPlugin');
		$errorPlugin->addException($exception);
	}

	private static function initDb() {
		$options = self::getBootstrap()->getOptions();
		$resource = self::getBootstrap()->getPluginResource('db');
		$resource->init();
		$db = $resource->getDbAdapter();
		$db->query('SET NAMES '.$options['resources']['db']['charset']);
		self::setDbGiteNouette($db);
	}

	private static function initLog($availableDb = true) {
		$logger = new Zend_Log();
		$options = self::getBootstrap()->getOptions();

		// Writer DB
		if ($availableDb && $options['log']['db']['actif']) {
			$db = self::getDbGiteNouette();
			if (!is_null($db)) {
				$columnMapping = array('priority' => 'priority', 'message' => 'message', 'username' => 'username');
				$logger->setEventItem('username', 'root');
				$dbWriter = new Zend_Log_Writer_Db($db,'core_log',$columnMapping);
				$logger->addWriter($dbWriter);
			}
			else {
				$availableDb = false;
			}
		}

		// Writer Mail
		if ($options['log']['mail']['actif'] || !$availableDb ) {
			$mail = new Zend_Mail();
			$mail->setFrom($options['app']['mail'])
			->addTo($options['admin']['mail']);
			$mailWriter = new Zend_Log_Writer_Mail($mail);
			$mailWriter->addFilter(Zend_Log::EMERG);
			$logger->addWriter($mailWriter);
		}

		self::setLogger($logger);
	}

	private static function load($cache, $id, $fn) {
		$options = self::getBootstrap()->getOptions();
		if (!$data = $cache->load($id, !$options['cache']['validity']['test'])) {
			$data = $fn();
			$cache->save($data, $id);
			self::getLogger()->log(sprintf("New cache saved with id(=%s)", $id), Zend_Log::INFO);
		}
		return $data;
	}

	public static function loadCache($id, $fn) {
		$cache = self::getCache();
		return self::load($cache, $id, $fn);
	}

	public static function loadPageCache($id, $fn) {
		$cache = self::getPageCache();
		return self::load($cache, $id, $fn);
	}

	public static function getCurrentStackTrace($message) {
		try {
			throw new Exception($message);
		}
		catch (Exception $e) {
			$print = $message;
			$stack = $e->getTrace();
			array_shift($stack);
			foreach ($stack as $number => $trace) {
				ob_start();
				var_dump($trace['args']);
				$args = ob_get_clean();
				$print .= sprintf("\n#%s %s(%s): %s(%s)", $number, $trace["file"], $trace['line'], $trace['function'], $args);
			}
			return $print;
		}
	}
}